//
//  StatsManager.m
//  Autismus
//
//  Created by Nicolas CHENG on 14/01/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "BMAStatsManager.h"
#import "BMAGame.h"
#import "BMAAnswer.h"
#import "NSDate+BMAAdditions.h"

#define BMACOEFF 2

@implementation BMAStatsManager

#pragma mark -
#pragma Singleton

+ (id)sharedInstance
{
    DEFINE_SHARED_INSTANCE_USING_BLOCK(^{
        return [[self alloc] init];
    });
}

#if DEBUG
// Création de données pour des tests pour des dates précédentes à celle en cours
// Le paramètre équivaut au nombre de jours désirés
- (void)test:(NSUInteger)value includeToday:(BOOL)includeToday
{
    // reinit de toute la base
    NSArray *fetchResults = [BMAGame fetchEntities];
    if (fetchResults && [fetchResults count] > 0) [BMAGame deleteEntities:fetchResults];
    
    // création d'un nouveau jeu de données
    NSDate *date = [NSDate date];
    
    for (NSUInteger i = 0; i < value; i++)
    {
        if (includeToday == NO)
        {
            date = [date yesterday];
            includeToday = YES;
        }
        
        NSUInteger count1 = RAND_INT_VAL(5, 5);             // parties jouées par jour (1 partie toutes les heures)
        
        for (NSUInteger j = 0; j < count1; j++)
        {
            BMAGame *game = [[BMAGame alloc] initEntity];
            game.startDate = [date dateByReplacingTimeWith:(1 + j) minute:0 second:0];
            
            NSUInteger interval1 = RAND_INT_VAL(3, 8);      // durée des parties en minute
            game.endDate = [game.startDate dateByAddingTimeInterval:(60 * interval1)];
            
            NSUInteger idGame = RAND_INT_VAL(0, 2);         // type de partie
            game.idGame = [NSNumber numberWithInt:idGame];
            
            // answers
            NSUInteger count2 = RAND_INT_VAL(8, 20);        // réponses par parties
            BOOL value = NO;
            for (NSUInteger k = 0; k < count2; k++)
            {
                BMAAnswer *answer = [[BMAAnswer alloc] initEntity];
                answer.game = game;
                
                NSUInteger level = RAND_INT_VAL(0, 2);      // level entre 0 et 2
                answer.level = [NSNumber numberWithInt:level];
                
                value = (RAND_INT_VAL(0, 1) == 0) ? NO : YES;
                answer.value = [NSNumber numberWithBool:value];
                
                // à implémenter selon le jeu joué
                //startDate;
                //endDate;
                
                [game addAnswersObject:answer];
            }
        }
        
        [BMAGame saveContext];
    }
}

#endif

// Coeff pour chaque bonne réponse par jeu et par level
- (CGFloat)coefficientForGame:(BMAIDGame)value level:(NSUInteger)level
{
    return BMACOEFF;
}

// Scrore pour une date donnée
- (CGFloat)scoreForDate:(NSDate *)value
{
    __block CGFloat result = 0;
    
    /*
    NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
        BMAGame *game = (BMAGame *)evaluatedObject;
        return [game.startDate isEqualToDateIgnoringTime:value];
    }];
    */
    
    NSDate *date1 = [value dateByReplacingTimeWith:0 minute:0 second:0];
    NSDate *date2 = [value dateByReplacingTimeWith:23 minute:59 second:59];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ <= startDate AND startDate <= %@ AND anwser == %@", date1, date2, [NSNumber numberWithBool:YES]];
    
    NSArray *fetchResults = [BMAGame fetchEntitiesWithPredicate:predicate andSortDescriptor:nil];
    
    for (BMAGame *game in fetchResults)
    {        
        [game.answers enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
            BMAAnswer *answer = (BMAAnswer *)obj;
            //if ([answer.value boolValue])
            //{
                result += [answer.level intValue] * [self coefficientForGame:[answer.game.idGame intValue] level:[answer.level intValue]];
            //}
        }];
    }
    
    return result;
}

// Temps passé pour la totalité des jeux pour une date donnée
- (NSTimeInterval)elapsedTimeForDate:(NSDate *)value
{
    NSTimeInterval result = 0; 
    
    /*
    NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
        BMAGame *game = (BMAGame *)evaluatedObject;
        return [game.startDate isEqualToDateIgnoringTime:value];
    }];
    */
    
    NSDate *date1 = [value dateByReplacingTimeWith:0 minute:0 second:0];
    NSDate *date2 = [value dateByReplacingTimeWith:23 minute:59 second:59];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ <= startDate AND startDate <= %@", date1, date2];
    
    
    NSArray *fetchResults = [BMAGame fetchEntitiesWithPredicate:predicate andSortDescriptor:nil];
    
    for (BMAGame *game in fetchResults)
    {        
        result += ABS([game.startDate timeIntervalSinceDate:game.endDate]);
    }
    
    return result;
}

// Temps passé sur les jeux depuis le tout début
- (NSTimeInterval)elapsedTimeSinceTheBeginning
{    
    NSTimeInterval result = 0;
    
    NSArray *fetchResults = [BMAGame fetchEntities];
    
    for (BMAGame *game in fetchResults)
    {        
        result += ABS([game.startDate timeIntervalSinceDate:game.endDate]);
    }
    
    return result;
}

// Temps passé par exercice et par jour en pourcentage
- (NSUInteger)percentElapsedTimeForDate:(NSDate *)value idGame:(BMAIDGame)idGame
{
    NSUInteger result = 0;
    
    /*
    NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
        BMAGame *game = (BMAGame *)evaluatedObject;
        BOOL result = [game.startDate isEqualToDateIgnoringTime:value];
        result = result && ([game.idGame intValue] == idGame);
        return result;
    }];
    */
    
    NSDate *date1 = [value dateByReplacingTimeWith:0 minute:0 second:0];
    NSDate *date2 = [value dateByReplacingTimeWith:23 minute:59 second:59];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ <= startDate AND startDate <= %@ AND idGame == %d", date1, date2, idGame];
    
    NSArray *fetchResults = [BMAGame fetchEntitiesWithPredicate:predicate andSortDescriptor:nil];
    
    NSTimeInterval elapsedTimeForGame = 0;
    
    for (BMAGame *game in fetchResults)
    {
        elapsedTimeForGame += ABS([game.startDate timeIntervalSinceDate:game.endDate]);
    }
    
    NSTimeInterval elapsedTimeForAllGames = [self elapsedTimeForDate:value];
    
    result = elapsedTimeForGame/elapsedTimeForAllGames * 100;
    
    return result;
}

// Tableaux de parties pour une date donnant le temps passé avec le score 
- (NSArray *)gameStatsForDate:(NSDate *)value
{
    NSMutableArray *result = [[NSMutableArray alloc] initWithCapacity:0];
    
    /*
    NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
        BMAGame *game = (BMAGame *)evaluatedObject;
        return [game.startDate isEqualToDateIgnoringTime:value];
    }];
    */

    NSDate *date1 = [value dateByReplacingTimeWith:0 minute:0 second:0];
    NSDate *date2 = [value dateByReplacingTimeWith:23 minute:59 second:59];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ <= startDate AND startDate <= %@", date1, date2];
    
    NSArray *fetchResults = [BMAGame fetchEntitiesWithPredicate:predicate andSortDescriptor:[NSSortDescriptor sortDescriptorWithKey:@"startDate" ascending:YES]];
    
    NSUInteger index = 0;
    
    __block NSTimeInterval maxElapsedTime = 0;
    __block NSUInteger maxScore = 0;
    
    for (BMAGame *game in fetchResults)
    {
        __block CGFloat score = 0;
        __block NSTimeInterval elapsedTime = 0;
        
        [game.answers enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
            BMAAnswer *answer = (BMAAnswer *)obj;
            if ([answer.value boolValue])
            {
                score += [answer.level intValue] * [self coefficientForGame:[answer.game.idGame intValue] level:[answer.level intValue]];
            }
            
            elapsedTime += ABS([game.startDate timeIntervalSinceDate:game.endDate]);
            
            if (elapsedTime > maxElapsedTime)
            {
                maxElapsedTime = elapsedTime;
            }
        }];
        
        BMAStats *stat = [[BMAStats alloc] init];
        stat.date = game.startDate;
        stat.score = score;
        stat.elapsedTime = elapsedTime;
        stat.idGame = [game.idGame intValue];
        stat.index = index;
        
        if (score > maxScore)
        {
            maxScore = score;
        }
        
        [result addObject:stat];
        
        index++;
    }
    
    [result enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        BMAStats *stat = (BMAStats *)obj;
        stat.maxElapsedTime = maxElapsedTime;
        stat.maxScore = maxScore;
    }];
    
    return result;
}

@end
